package com.lp.guoguo.config;

import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.JSONWriter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lp.guoguo.annotation.DecryptBody;
import com.lp.guoguo.common.BusinessException;
import com.lp.guoguo.common.ResultCode;
import com.lp.guoguo.constant.RSAConsts;
import com.lp.guoguo.model.EncryptedRequest;
import com.lp.guoguo.util.RSAUtil;
import org.springframework.core.MethodParameter;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import jakarta.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.stream.Collectors;

public class DecryptBodyArgumentResolver implements HandlerMethodArgumentResolver {
    private final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(DecryptBody.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
        String body = getRequestBody(request);
        // 解析原始请求
        EncryptedRequest encryptedRequest = null;
        try {
//             encryptedRequest = objectMapper.readValue(body, EncryptedRequest.class);

            HashMap<String, String> requestMap =  objectMapper.readValue(body, HashMap.class);
            String sign = requestMap.get("sign");

            if (StringUtils.hasText(sign)) {
                requestMap.remove("sign");
                String jsonString = JSONObject.toJSONString(requestMap, JSONWriter.Feature.SortMapEntriesByKeys);

                if (RSAUtil.checkSign(jsonString, sign, RSAConsts.publicAppKey)) {
                    String msgCiphertext = requestMap.get("msgCiphertext");
                    if (StringUtils.hasText(msgCiphertext)) {
                        String decryptedMsg = RSAUtil.decryptSplit(msgCiphertext, RSAConsts.privateKey);
                        return objectMapper.readValue(decryptedMsg, parameter.getParameterType());
                    }
                }else {
                    throw new BusinessException(ResultCode.RSA_VERIFY_ERROR);
                }
            }

        }catch (Exception e){
            throw new BusinessException(ResultCode.VALIDATE_FAILED);
        }

        // 解析 msgCiphertext 中的实际内容
        return objectMapper.readValue(encryptedRequest.getMsgCiphertext(), parameter.getParameterType());
    }

    private String getRequestBody(HttpServletRequest request) throws IOException {
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream(), StandardCharsets.UTF_8))) {
            return reader.lines().collect(Collectors.joining());
        }
    }
} 